<script setup lang="ts">
import { RefreshRight } from "@element-plus/icons-vue"
import { onMounted, ref } from "vue"
import { IGetStudentByCardIdResponseData } from "@/api/student/types/student"
import { getStudentByCardIdApi } from "@/api/student"
import { useUserStore } from "@/store/modules/user"
import { IStudentInfoData } from "@/api/login/types/login"
import { usePagination } from "@/hooks/usePagination"
import dayjs from "@/utils/day"
import FileSaver from "file-saver"
import { showPromptMessage } from "@/utils"
import JsPDF from "jspdf"
import jsZip from "jszip"
import { useFullscreenLoading } from "@/hooks/useFullscreenLoading"

const { paginationData, handleCurrentChange, handleSizeChange } = usePagination()
const userStore = useUserStore()
const drawData = ref({
  headmaster: ""
})
const TableData = ref<IGetStudentByCardIdResponseData[]>([])
const userInfo = ref<IStudentInfoData>(userStore.userInfo as IStudentInfoData)
const getTableData = () => {
  getStudentByCardIdApi({ id: userInfo.value.identityCardId, studentId: undefined })
    .then((res) => {
      paginationData.total = res.data.total
      TableData.value = res.data.graduateInfo
      drawData.value.headmaster = res.data.headmaster
    })
    .catch(() => {
      TableData.value = []
    })
}

getTableData()

const handleRefresh = () => {
  getTableData()
}

const setBackground = (ctx: CanvasRenderingContext2D | null, bgImageUrl: string) => {
  if (!ctx) return
  return new Promise((resolve) => {
    const image = new Image()
    image.src = bgImageUrl
    image.onload = () => {
      if (canvas) {
        canvas.width = image.width
        canvas.height = image.height
      }
      ctx.drawImage(image, 0, 0)
      resolve(true)
    }
  })
}
// 初始化画布
const pdfDoc = new JsPDF()
const zip = new jsZip()
let canvas: null | HTMLCanvasElement = null
const pdfsData = ref<{ blob: Blob; fileName: string }[]>([])
let ctx: CanvasRenderingContext2D | null = null
const canvasData = ref<{
  generateTime: {
    year: string
    month: string
    day: string
  }
  graduateTime: {
    year: string
    month: string
    day: string
  }
  enrollmentTime: {
    year: string
    month: string
    day: string
  }
}>({
  generateTime: {
    year: "",
    month: "",
    day: ""
  },
  enrollmentTime: {
    year: "",
    month: "",
    day: ""
  },
  graduateTime: {
    year: "",
    month: "",
    day: ""
  }
})
const initCanvas = () => {
  canvas = document.getElementById("myCanvas") as HTMLCanvasElement
  // 创建画布上下文对象
  ctx = canvas.getContext("2d")
}

const drawText = (
  ctx: CanvasRenderingContext2D,
  text: string,
  x: number | "middle",
  y: number,
  size: number,
  color = "#000"
) => {
  ctx.font = `${size}px 黑体 bold`
  ctx.fillStyle = color
  if (x === "middle") {
    const textWidth = ctx.measureText(text).width
    const canvasWidth = canvas!.width
    const xPosition = canvasWidth / 2 - textWidth / 2
    ctx.fillText(text, xPosition, y)
  } else {
    ctx.fillText(text, x, y)
  }
}
const drawImage = (ctx: CanvasRenderingContext2D, imageUrl: string, x: number, y: number) => {
  return new Promise((resolve) => {
    const image = new Image()
    image.src = imageUrl
    image.setAttribute("crossOrigin", "Anonymous")
    image.onload = () => {
      ctx.drawImage(image, x, y, 350, 534)
      resolve(true)
    }
    image.onerror = () => {
      showPromptMessage("error", "证件照生成失败")
      resolve(true)
    }
  })
}
const exportOptionVisible = ref(false)
const exportOptionData = ref({
  hasIdentificationPhotoUrl: "no",
  type: "1"
})

const currentDownload = ref<IGetStudentByCardIdResponseData>()
const currentExport = ref<IGetStudentByCardIdResponseData | undefined>(undefined)
const diplomaData = ref<IGetStudentByCardIdResponseData>()
const handleDownload = async () => {
  const row = currentDownload.value
  if (!row?.certificateNo) {
    return showPromptMessage("error", "证书未生成,无法导出")
  }
  currentExport.value = row
  exportOptionVisible.value = true
  exportOptionData.value.hasIdentificationPhotoUrl = "no"
  // fullLoading.value = ElLoading.service({
  //   lock: true,
  //   text: "下载中..."
  // })
  // diplomaData.value = row
  // await individualGenerate(diplomaData.value)
  // fullLoading.value?.close()
}
const individualGenerateLoading = useFullscreenLoading(
  () => {
    diplomaData.value && individualGenerate(diplomaData.value)
  },
  {
    text: "下载中"
  }
)

const handleExport = () => {
  if (!currentExport.value) return
  if (exportOptionData.value.hasIdentificationPhotoUrl === "yes" && !currentExport.value.identificationPhotoUrl) {
    return showPromptMessage("error", "该学员还未上传证件照")
  }
  exportOptionVisible.value = false
  diplomaData.value = currentExport.value
  // individualGenerate(diplomaData.value)
  individualGenerateLoading()
}
const drawIndividualData = (data: IGetStudentByCardIdResponseData) => {
  if (!ctx || !canvas || !diplomaData.value) return
  drawText(ctx, data.name, "middle", 1330, 120, "#000")
  drawText(ctx, canvasData.value.graduateTime.year, canvas!.width / 2 - 230, 3194, 55, "#000")
  drawText(ctx, canvasData.value.generateTime.month, canvas!.width / 2 + 100, 3194, 55, "#000")
  drawText(ctx, canvasData.value.generateTime.day, canvas!.width / 2 + 350, 3194, 55, "#000")
  drawText(ctx, data.trainingInfo, "middle", 1750, 80, "#000")
  drawText(ctx, data.certificateNo, canvas!.width / 2 - 140, 2415, 65, "#000")
  drawText(ctx, canvasData.value.enrollmentTime.year, canvas!.width / 2 - 424, 1955, 52, "#000")
  drawText(ctx, canvasData.value.enrollmentTime.month, canvas!.width / 2 - 240, 1955, 52, "#000")
  drawText(ctx, canvasData.value.enrollmentTime.day, canvas!.width / 2 - 130, 1955, 52, "#000")
  drawText(ctx, canvasData.value.graduateTime.year, canvas!.width / 2 + 10, 1955, 52, "#000")
  drawText(ctx, canvasData.value.graduateTime.month, canvas!.width / 2 + 203, 1955, 52, "#000")
  drawText(ctx, canvasData.value.graduateTime.day, canvas!.width / 2 + 315, 1955, 52, "#000")
}
const individualAsyncTask = async (info: IGetStudentByCardIdResponseData) => {
  canvasData.value.enrollmentTime = {
    year: dayjs(info.enrollmentTime).format("YYYY"),
    month: dayjs(info.enrollmentTime).format("MM"),
    day: dayjs(info.enrollmentTime).format("DD")
  }
  canvasData.value.graduateTime = {
    year: dayjs(info.graduateTime).format("YYYY"),
    month: dayjs(info.graduateTime).format("MM"),
    day: dayjs(info.graduateTime).format("DD")
  }
  canvasData.value.generateTime = {
    year: dayjs(info.creationTime).format("YYYY"),
    month: dayjs(info.creationTime).format("MM"),
    day: dayjs(info.creationTime).format("DD")
  }
  if (canvas && ctx) {
    // TODO:更换证明书背景
    await setBackground(ctx, "/images/cer2.jpg")
    drawIndividualData(info)
    if (info.identificationPhotoUrl && exportOptionData.value.hasIdentificationPhotoUrl === "yes") {
      await drawImage(ctx, info.identificationPhotoUrl, 1732, 914)
    }
    const pdfString = getPdf(canvas)
    addPdf(pdfString, `${info.name}-${info.projectName}结业证明书`)
    // await setBackground(ctx, "/images/certificate2.png")
    // drawIndividualData(info)
    // if (info.identificationPhotoUrl && exportOptionData.value.hasIdentificationPhotoUrl === "yes") {
    //   await drawImage(ctx, info.identificationPhotoUrl, 1732, 914)
    // }
    // const pdfString2 = getPdf(canvas)
    // addPdf(pdfString2, `${info.name}-${info.projectName}证书2`)
  }
}

const getPdf = (canvas: HTMLCanvasElement) => {
  // 将Canvas转换为图片数据
  return canvas.toDataURL("image/jpeg", 1.0)
}
const addPdf = (dataURL: string, fileName: string) => {
  pdfDoc.addImage(dataURL, "JPEG", 0, 0, 210, 297)
  const blob = pdfDoc.output("blob")
  pdfsData.value.push({ blob: blob, fileName })
}

const individualGenerate = async (graduateInfo: IGetStudentByCardIdResponseData) => {
  await individualAsyncTask(graduateInfo)
  pdfsData.value.forEach((data) => {
    zip.file(`${data.fileName}.pdf`, data.blob)
  })
  zip.generateAsync({ type: "blob" }).then((content) => {
    FileSaver.saveAs(
      content,
      graduateInfo.name +
        graduateInfo.projectName +
        "结业证明书-" +
        (exportOptionData.value.hasIdentificationPhotoUrl === "yes" ? "有证件照" : "无证件照") +
        ".zip"
    )
  })
}

const realName = ref("")
const showNameInput = ref(false)
const handleClickUpload = (row: any) => {
  showNameInput.value = true
  currentDownload.value = row
}
const confirName = () => {
  if (userInfo.value.name === realName.value) {
    showNameInput.value = false
    handleDownload()
  } else {
    showPromptMessage("error", "您输入的姓名不正确")
  }
}

onMounted(() => {
  initCanvas()
})
</script>

<template>
  <div class="app-container">
    <el-card shadow="never">
      <div class="flex justify-end">
        <el-tooltip content="刷新表格">
          <el-button type="primary" :icon="RefreshRight" circle @click="handleRefresh" />
        </el-tooltip>
      </div>
      <div class="mt-2">
        <el-table :data="TableData">
          <el-table-column prop="name" label="姓名" align="center" />
          <el-table-column prop="projectName" label="项目名称" align="center" />
          <el-table-column prop="certificateNo" label="证书编号" align="center" />
          <el-table-column prop="enrollmentTime" label="入学时间" align="center">
            <template #default="scope">
              {{ dayjs(scope.row.enrollmentTime).format("YYYY-MM-DD") }}
            </template>
          </el-table-column>
          <el-table-column prop="graduateTime" label="结业时间" align="center">
            <template #default="scope">
              {{ dayjs(scope.row.graduateTime).format("YYYY-MM-DD") }}
            </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作" width="220" align="center">
            <template #default="scope">
              <el-button type="primary" text bg size="small" @click="handleClickUpload(scope.row)">下载</el-button>
              <!--              <el-button type="danger" text bg size="small" @click="handleDelete(scope.row)">删除</el-button>-->
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="mt-2">
        <el-pagination
          background
          :layout="paginationData.layout"
          :page-sizes="paginationData.pageSizes"
          :total="paginationData.total"
          :page-size="paginationData.pageSize"
          :currentPage="paginationData.currentPage"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>
    <canvas id="myCanvas" />

    <el-dialog title="导出选项" v-model="exportOptionVisible" width="50%">
      <!-- {{ exportOptionData.hasIdentificationPhotoUrl }} -->
      <el-form :model="exportOptionData" label-width="110">
        <el-form-item label="是否包含证件照" v-if="exportOptionData.type === '1'">
          <el-radio-group v-model="exportOptionData.hasIdentificationPhotoUrl">
            <el-radio label="yes">有证件照</el-radio>
            <el-radio label="no">无证件照</el-radio>
          </el-radio-group>
        </el-form-item>
        <!-- <el-form-item label="导出类型">
          <el-radio-group v-model="exportOptionData.type">
            <el-radio label="1">结业证书</el-radio>
            <el-radio label="2">结业证明书</el-radio>
          </el-radio-group>
        </el-form-item> -->
      </el-form>

      <template #footer>
        <el-button @click="exportOptionVisible = false">取消</el-button>
        <el-button type="primary" @click="handleExport">确认</el-button>
      </template>
    </el-dialog>

    <el-dialog
      @closed="
        () => {
          realName = ''
        }
      "
      title="提示"
      v-model="showNameInput"
      width="500px"
      ><div class="input-name-box">
        <span>本人</span>
        <el-input style="width: 100px" v-model="realName" />
        <span class="break-all">
          承诺：上传的照片为个人真实信息，证明书信息为本人学习经历，如有虚假，所造成后果由本人承担。
        </span>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-space>
            <el-button
              @click="
                () => {
                  showNameInput = false
                }
              "
              >取消</el-button
            >
            <el-button type="primary" @click="confirName">确认</el-button>
          </el-space>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
canvas {
  width: 0;
  height: 0;
}

.input-name-box {
  line-height: 40px;
}
.input-name-box :deep(.el-input) {
  border-bottom: 1px solid #ccc;
}
.input-name-box :deep(.el-input__wrapper) {
  box-shadow: none;
}
</style>
